"use strict";

const { logger } = require("ee-core/log");
const { v4: uuidv4 } = require("uuid");
const { post, get } = require("../../utils/request");

const { browserService } = require("../../service/browser");
// 定义 sleep 函数
async function sleep(second) {
  return new Promise((resolve) => setTimeout(resolve, second * 1000));
}

const resUrl = {
  rzspss: [
    "/aweme/v1/web/discover/search/",
    "/aweme/v1/web/general/search/single/",
    "/aweme/v1/web/aweme/detail/",
    "/aweme/v1/web/aweme/post/",
  ],
  spplhq: ["/aweme/v1/web/comment/list/", "/aweme/v1/web/comment/list/reply/"],
  hqplrxx: ["/aweme/v1/web/user/profile/other/"],
};
async function onResonse(response, action, flowNo) {
  const myUrl = new URL(response.url());
  const path = myUrl.pathname;
  const filteredUrls = resUrl[action].filter((url) => url === path);
  if (filteredUrls.length > 0) {
    logger.info("[child-process] onResonse ", path);
    const text = await response.text();
    post(
      "http://electron-egg.local.com:42080/api/v1/crawler/dataSync/rawData/douyin",
      {
        url: response.url(),
        rawData: text,
        flowNo: flowNo,
      }
    )
      .then((res) => {
        logger.info(res);
      })
      .catch((e) => {
        logger.info("[child-process] onResonse error: ", e);
      });
  }
}
async function mouseWheel(page, size) {
  const body = await page.waitForSelector("body");
  const bodySize = await page.evaluate(() => {
    const body = document.body;
    return {
      width: body.offsetWidth,
      height: body.offsetHeight,
    };
  });
  logger.info("body 元素宽度:", bodySize.width);
  logger.info("body 元素高度:", bodySize.height);
  // 移动鼠标到指定位置
  await page.mouse.move(bodySize.width / 2, bodySize.height / 2);
  await sleep(1);
  // 模拟向上滚动
  await page.mouse.wheel(0, bodySize.height / size);
}

/**
 * example - TimerJob
 * @class
 */
class TaskHandleJob {
  constructor() {
    this.isStart = false;
    this.isPause = false;
    this.version = 0;
    this.config = {
      serverAddress: "http://electron-egg.local.com:42080",
      taskApi: "/api/v1/task?status=dzx",
      dataSyncUrl: "/api/v1/crawler/dataSync/rawData/douyin",
    };
    this.browserService = browserService;
  }

  /**
   * handle()方法是必要的，且会被自动调用
   * params 传递的参数
   */
  async handle(params) {
    logger.info("[child-process] TimerJob params:11111111111 ", params);
    const { jobId } = params;
    this.isStart = true;
    this.version++;
    await this.doTimer(jobId);
    logger.info("[child-process] TimerJob doTimer");
  }

  /**
   * 暂停任务运行
   */
  async pause(jobId) {
    logger.info("[child-process] Pause timerJob, jobId: ", jobId);
    this.isPause = true;
  }

  /**
   * 恢复任务运行
   */
  async resume(jobId, pid) {
    logger.info(
      "[child-process] Resume timerJob, jobId: ",
      jobId,
      ", pid: ",
      pid
    );
    this.isPause = false;
  }

  canRund(tv) {
    return this.isStart && tv === this.version;
  }

  /**
   * 运行任务
   */
  async doTimer(jobId) {
    // 计时器模拟任务
    const eventName = "job-timer-progress-" + jobId;
    logger.info("[child-process] TimerJob start, eventName: ", eventName);
    const tv = this.version;
    const browserContext = await this.browserService.getBrowserContext("SP1");
    const sleepSecone = 10;
    while (this.canRund(tv)) {
      if (this.isPause) {
        await sleep(sleepSecone);
        continue;
      }
      if (!browserContext) {
        logger.info("[child-process] browserContext is null");
        await sleep(sleepSecone);
        continue;
      }
      let allTask = await get(this.config.serverAddress + this.config.taskApi);
      logger.info("[child-process] allTask: ", allTask);
      if (allTask.length === 0) {
        logger.info("[child-process] no task");
        await sleep(sleepSecone);
        continue;
      }
      for (let index = 0; index < allTask.length; index++) {
        const task = allTask[index];
        logger.info("[child-process] task: ", task);
        logger.info(`浏览器上下文:${JSON.stringify(browserContext.pages())}`);
        get(`http://electron-egg.local.com:42080/api/v1/task/${task.id}/zxz`);
        switch (task.taskCode) {
          case "rzspss":
            await this.rzspss(browserContext, task);
            break;
          case "spplhq":
            await this.spplhq(browserContext, task);
            break;
          case "hqplrxx":
            await this.hqplrxx(browserContext, task);
            break;
          default:
            break;
        }
      }
      await sleep(sleepSecone);
    }
  }

  async rzspss(context, task) {
    const cts = JSON.parse(task.context);
    logger.info("[child-process] rzspss task: ", task);
    const pageUrl = `https://www.douyin.com/root/search/${
      cts.keyword
    }?aid=${uuidv4()}&type=general`;
    logger.info("[child-process] pageUrl: ", pageUrl);
    const page = await context.newPage();
    page.on("response", async (response) => {
      await onResonse(response, "rzspss", task.flowNo);
    });
    await page.goto(pageUrl, { timeout: 30000 });
    const slector = {
      pxyj: {
        综合排序: [1, 2],
        最新发布: [1, 3],
        最多点赞: [1, 4],
      },
      fbsj: {
        不限: [2, 2],
        一天内: [2, 3],
        一周内: [2, 4],
        半年内: [2, 5],
      },

      spsc: {
        不限: [3, 2],
        "1分钟以下": [3, 3],
        "1-5分钟": [3, 4],
        "5分钟以上": [3, 5],
      },
      ssfw: {
        不限: [4, 2],
        关注的人: [4, 3],
        最近看过: [4, 4],
        还未看过: [4, 5],
      },

      nrxs: {
        不限: [5, 2],
        视频: [5, 3],
        图文: [5, 4],
      },
    };
    let shaixuan;
    const array = ["pxyj", "fbsj", "spsc", "ssfw", "nrxs"];
    const start =
      "#search-content-area > div > div.eVQDrSwo > div.qWNh2IMg.CRPlkYAk.j7kc7ENz > div.ZyB0s4zV > div > div > div.jjU9T0dQ";
    for (let index = 0; index < array.length; index++) {
      const tag = array[index];
      const va = cts[tag];
      if (va == "不限" || va === "综合排序") {
        continue;
      }
      if (!shaixuan) {
        shaixuan = await page.waitForSelector(`${start} > span`, {
          timeout: 10000,
        });
        await shaixuan.hover();
      }
      const point = slector[tag][va];
      const item = await page.waitForSelector(
        `${start} > div > div:nth-child(${point[0]}) > span:nth-child(${point[1]})`,
        {
          timeout: 10000,
        }
      );
      item.click();
      await sleep(2);
    }
    let a = 0;
    do {
      a++;
      await mouseWheel(page, 1);
      const singleElementByCSS = await page.$(
        "#waterFallScrollContainer > div.nU717OFZ"
      );
      if (singleElementByCSS) {
        logger.info("通过 CSS 选择器找到单个元素");
        break;
      }
    } while (a < 50);
    get(`http://electron-egg.local.com:42080/api/v1/task/${task.id}/ywc`);
  }

  async spplhq(context, task) {
    const awemeList = await get(
      `http://electron-egg.local.com:42080/api/v1/aweme?flowNo=${task.flowNo}`
    );
    if (awemeList.length == 0) {
      get(`http://electron-egg.local.com:42080/api/v1/task/${task.id}/ywc`);
      return;
    }
    logger.info("awemeList: ", awemeList);
    const page = await context.newPage();
    page.on("response", async (response) => {
      await onResonse(response, "spplhq", task.flowNo);
    });
    for (let index = 0; index < awemeList.length; index++) {
      const awemeId = awemeList[index];
      const pageUrl = `https://www.douyin.com/video/${awemeId}`;
      logger.info("[child-process] pageUrl: ", pageUrl);
      await page.goto(pageUrl, { timeout: 30000 });
      let a = 0;
      do {
        a++;
        await mouseWheel(page, 2);
        try {
          const singleElementByCSS = await page.waitForSelector(
            "#douyin-right-container > div.parent-route-container.route-scroll-container.h5AVrOfS > div > div > div.leftContainer.gkVJg5wr > div.KwRNeXA3 > div > div > div.HV3aiR5J.comment-mainContent > div.fanRMYie.cDj65BDb",
            { timeout: 100 }
          );
          break;
        } catch (e) {}
        const currentUrl = await page.url();
        console.log("当前页面的 URL 是:", currentUrl);
        if (currentUrl.includes("note")) {
          this.note(page);
          break;
        } else if (!currentUrl.includes("video")) {
          break;
        }
      } while (a < 50);
      get(`http://electron-egg.local.com:42080/api/v1/awemeMark/${awemeId}`);
    }
    get(`http://electron-egg.local.com:42080/api/v1/task/${task.id}/ywc`);
  }
  async note(page) {
    const element = await page.waitForSelector(
      "#detailrelatedVideoCard > div > div.oVW6Ln4S.JNsnEzRC.VwvTNAQg.t6DFrTdr > div > div.TclYH4Qn.rFPL_gS_",
      { timeout: 5000 }
    );
    await element.click();
    const pinlun = await page.waitForSelector(
      "#merge-all-comment-container > div > div.HV3aiR5J.comment-mainContent.iV2CcAAV",
      { timeout: 3000 }
    );
    const box = await pinlun.boundingBox();
    // 移动鼠标到指定位置
    await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
    let a = 0;
    do {
      a++;
      console.log("note");

      await sleep(1);
      // 模拟向上滚动
      await page.mouse.wheel(0, box.height / 2);
      try {
        const end = await page.waitForSelector(
          "#merge-all-comment-container > div > div.HV3aiR5J.comment-mainContent.iV2CcAAV > div.fanRMYie",
          { timeout: 300 }
        );
        break;
      } catch (error) {
        console.log("使用 waitForSelector 未找到元素");
      }
    } while (a < 50);
  }

  async hqplrxx(context, task) {
    logger.info("[child-process] hqplrxx task: ", task);
    const secUidList = await get(
      `http://electron-egg.local.com:42080/api/v1/secUid?flowNo=${task.flowNo}`
    );
    if (secUidList.length == 0) {
      get(`http://electron-egg.local.com:42080/api/v1/task/${task.id}/ywc`);
      return;
    }
    logger.info("secUidList: ", secUidList);
    const page = await context.newPage();
    page.on("response", async (response) => {
      await onResonse(response, "hqplrxx", task.flowNo);
    });
    for (let index = 0; index < secUidList.length; index++) {
      const secUid = secUidList[index];
      const pageUrl = `https://www.douyin.com/user/${secUid}`;
      logger.info("[child-process] pageUrl: ", pageUrl);
      await page.goto(pageUrl, { timeout: 30000 });

      try {
        const element = await page.waitForSelector(
          "#user_detail_element > div > div.o1w0tvbC.F3jJ1P9_.InbPGkRv.W41XVmRl > div.SwoeMAEU.nWLhWdOv > div.ty_H89Vr > button.semi-button.semi-button-secondary.RH8TCnaE.z0c5Gipx.I4tJiW0Q > span",
          { timeout: 3000 }
        );
        logger.info("使用 waitForSelector 找到元素");
        await element.click();
      } catch (error) {
        logger.info(" hqplrxx 使用 waitForSelector 未找到元素");
      }
      get(`http://electron-egg.local.com:42080/api/v1/comment/${secUid}`);
      await sleep(5);
    }
  }
}

TaskHandleJob.toString = () => "[class TaskHandleJob]";
module.exports = TaskHandleJob;
